package com.leador.socket;

import android.os.Handler;
import android.util.Log;

import com.leador.module.ILocation;
import com.leador.socket.listener.SoConnectListener;
import com.leador.utils.Config;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.List;

/**
 * Created by liuha on 2016/9/14.
 */
public class SocketConnect {
    private Socket socket = null;
    private InetSocketAddress inetSocketAddress = null;
    private SoConnectListener soConnectListener = null;
    private String msg = null;
    private static Object readLock = new Object();
    private static Object writerLock = new Object();

    public SocketConnect(SoConnectListener soConnectListener){
        this.soConnectListener = soConnectListener;
    }

    /**
     * 获取输入流
     * @return
     */
    public DataInputStream getDataInputStram(){
        synchronized (readLock){
            if(socketIsConnect()){
                try {
                    InputStream inputStream = socket.getInputStream();
                    if (inputStream != null) {
                        return new DataInputStream(inputStream);
                    }else{
                        throw  new IOException();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }

    public void writeOutputStream(byte[] bytes,Handler handler){
        if(socketIsConnect()){
            synchronized (writerLock){
                try {
                    Socket s = null;
                    s = new Socket(Config.HOST, Config.PORT);
//                    Log.e("哈哈哈 可以发送了",""+new String(bytes));
                    List<ILocation> iLocationList = ILocation.jsonToList(new String(bytes));
                    if(iLocationList.size() != 0){
                        for(ILocation iLocation : iLocationList) {
                            String json = actionSocket(ILocation.socketBeanToJson(iLocation),s);
                            Log.e("socket result is上报结果",json);
                        }
                        if(baos != null){
                            baos.close();
                        }
                    }
                }
                catch (Exception e) {
                    if (handler != null) {
                        handler.obtainMessage(4).sendToTarget();
                    }
                }
            }
        }
        if (handler != null) {
            handler.obtainMessage(4).sendToTarget();
        }
    }

    private static ByteArrayOutputStream baos = null;
    public static String  actionSocket(String s1, Socket socket) throws Exception {
        byte[] b1 = s1.getBytes();
        byte[] b = intToByteArray1(b1.length);
        byte[] b2 = new byte[b.length + b1.length];
        System.arraycopy(b, 0, b2, 0, b.length);
        System.arraycopy(b1, 0, b2, b.length, b1.length);
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.write(b2);
        dos.flush();
        InputStream in = socket.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        byte[] rheadb = new byte[4];
        dis.read(rheadb);
        int rlen=byteToInt2(rheadb);
        byte[] buffer = new byte[1024];
        baos = new ByteArrayOutputStream();
        for (int i = dis.read(buffer); i > -1; i = dis.read(buffer)) {
            baos.write(buffer, 0, i);
            rlen -= i;
            if (rlen == 0)
                break;
        }
        byte[] result = baos.toByteArray();
        String resultStr = new String(result);
        baos.flush();
        return resultStr;
    }

    public static int byteToInt2(byte[] b) {
        int mask = 0xff;
        int temp = 0;
        int n = 0;
        for (int i = 0; i < 4; i++) {
            n <<= 8;
            temp = b[i] & mask;
            n |= temp;
        }
        return n;
    }

    public static byte[] intToByteArray1(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }

    /**
     * socket 连接
     */
    public void connect(){
        try {
            socket = new Socket();
            inetSocketAddress = new InetSocketAddress(Config.HOST, Config.PORT);
            socket.connect(inetSocketAddress);
            socket.setKeepAlive(true);
            if(socketIsConnect()){
                soConnectListener.connectSucess();
            }else{
                soConnectListener.disconnectSucess();
            }
        } catch (IOException e) {
            Log.e("socket"," connect failed");
            soConnectListener.disconnectSucess();
        }
    }

    /**
     * socket断开
     */
    public void disconnectSocket(){
        if(socket == null){
            msg = "socket is null";
            soConnectListener.failure(msg);
            return;
        }
        if(socketIsConnect()){
            try {
                socket.close();
            } catch (IOException e) {
                msg = e.getMessage();
                soConnectListener.failure(msg);
                e.printStackTrace();
            }finally {
                socket = null;
            }
        }

        //TODO 释放资源

    }

    /**
     * socket 是否连接
     * @return
     */
    public  boolean socketIsConnect() {
        if (socket == null) {
            return false;
        }
        return (socket.isConnected()) && (!socket.isClosed()) && (!socket.isInputShutdown()) && (!socket.isOutputShutdown());
    }
}
